package com.seari.custody.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.seari.custody.bean.*;
import com.seari.custody.component.MinIoUtil;
import com.seari.custody.enums.MeetingFileType;
import com.seari.custody.exception.BIZException;
import com.seari.custody.pojo.MessageBean;
import com.seari.custody.pojo.ValidList;
import com.seari.custody.service.MeetingFileService;
import com.seari.custody.service.OutLineProjectService;
import com.seari.custody.service.ProjectService;
import com.seari.custody.util.JwtTokenUtils;
import com.spire.xls.ConverterSetting;
import com.spire.xls.Workbook;
import com.spire.xls.Worksheet;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

import static com.seari.custody.util.JwtTokenUtils.TOKEN_HEADER;

/**
 * @author lxv1
 */
@RestController
@RequestMapping("/outlineProjects")
public class OutLineProjectController {
    @Autowired
    private OutLineProjectService outLineProjectService;
    @Autowired
    private MeetingFileService meetingFileService;
    @Autowired
    private MinIoUtil minIoUtil;
    @Autowired
    private ProjectService projectService;


    @GetMapping("/{projectId}")
    public MessageBean getProjectById(@PathVariable String projectId) {

        Map<String, Object> outLineProjectByProjectId = outLineProjectService.getOutLineProjectByProjectId(projectId);

        return MessageBean.success("获取监护大纲数据成功", outLineProjectByProjectId);
    }

    @GetMapping("/{projectId}/{time}")
    public MessageBean getProjectById(@PathVariable String projectId, @PathVariable String time) {

        OutlineProject outlineProject = outLineProjectService.qryOneByProjectIdAndCreateTime(projectId, time);

        return MessageBean.success("获取监护大纲数据成功", outlineProject);
    }

    /**
     * 更新技术要求表
     *
     * @param outlineProject
     * @return
     */
    @PostMapping("/update")
    public MessageBean updateProject(@RequestBody OutlineProject outlineProject) {
        Integer integer = outLineProjectService.updateOutLineProject(outlineProject);
        return MessageBean.success("更新监护大纲数据成功", integer);
    }

    /**
     * 生成技术要求表
     *
     * @param outlineProjectData
     * @return
     */
    @PostMapping("/genData")
    public MessageBean genData(@RequestBody OutlineProjectData outlineProjectData) {
        Preconditions.checkArgument(!Strings.isNullOrEmpty(outlineProjectData.getLevel()), "监护等级不可为空");
        outLineProjectService.genData(outlineProjectData);

        return MessageBean.success("解析数据成功");
    }

    /**
     * 解析文档获取参数
     *
     * @return
     */
    @PostMapping("/projectInfo/{projectId}")
    public MessageBean getProjectInfo(@PathVariable String projectId) {

        OutlineParseVO projectInfo = outLineProjectService.getProjectInfo(projectId);

        return MessageBean.success("获取模板数据成功", projectInfo);
    }

    /**
     * 计算监护等级
     *
     * @param dataList
     * @return
     */
    @PostMapping("/calcLevel")
    public MessageBean calcLevel(@RequestBody @Valid ValidList<OutlineProjectData> dataList) {
        Map<String, String> level = outLineProjectService.level(dataList.getList());
        return MessageBean.success("计算监护等级成功", level);
    }

    /**
     * 获取参数
     */
    @PostMapping("/parse/{projectId}/{projectType}")
    public MessageBean parseFile(@PathVariable String projectId, @PathVariable String projectType) {
        HashMap<String, List<OutLineFileDataDTO>> stringListHashMap = outLineProjectService.parseFile(projectId, projectType);
        return MessageBean.success("获取模板数据成功", stringListHashMap);
    }

    /**
     * 推送给报审
     *
     * @param projectId
     * @return
     */
    @GetMapping("/push/{projectId}")
    public MessageBean push(@PathVariable String projectId) {
        outLineProjectService.pushData2JS(projectId);
        return MessageBean.success("推送成功");
    }

    /**
     * 反馈技术要求表
     *
     * @param outlineProject
     * @return
     */
    @PostMapping("/feedBack")
    public MessageBean feedBack(@RequestBody OutlineProject outlineProject) {
        outLineProjectService.feedBack(outlineProject);
        return MessageBean.success("成功");
    }


    /**
     * 监护大纲文件
     *
     * @param projectId
     * @return
     */
    @GetMapping(value = "/file/{projectId}")
    public MessageBean getOutlineProjectFile(@PathVariable String projectId, @RequestHeader(value = TOKEN_HEADER, defaultValue = "") String token) {
        Preconditions.checkArgument(StringUtils.isNotEmpty(token), "token不能为空");
        String userNumber = JwtTokenUtils.getUserNumber(token.substring(JwtTokenUtils.TOKEN_PREFIX.length()));
        String fileLink = outLineProjectService.getOutlineProjectFile(projectId, userNumber, MeetingFileType.OUTLINE_PROJECT_WORD);
        return MessageBean.success("获取监护大纲文件成功", fileLink);
    }

    /**
     * 预览监护大纲文件
     *
     * @param projectId
     * @return
     */
    @GetMapping(value = "/preview/file/{projectId}")
    public MessageBean getPreviewOutlineProjectFile(@PathVariable String projectId, @RequestHeader(value = TOKEN_HEADER, defaultValue = "") String token) {
        Preconditions.checkArgument(StringUtils.isNotEmpty(token), "token不能为空");
        String userNumber = JwtTokenUtils.getUserNumber(token.substring(JwtTokenUtils.TOKEN_PREFIX.length()));
        String fileLink = outLineProjectService.getOutlineProjectFile(projectId, userNumber, MeetingFileType.OUTLINE_PROJECT_PDF);
        return MessageBean.success("获取监护大纲文件成功", fileLink);
    }

    /**
     * 报审推过来的监护大纲文件
     *
     * @return
     */
    @PostMapping(value = "/file")
    public MessageBean syncOutlineFile(@Valid @RequestBody OutlineProjectPO outlineProjectPO) {
        String projectId = Optional.ofNullable(projectService.qryByProjectNo(outlineProjectPO.getProjectNo())).orElseThrow(() -> new BIZException("查无此项目")).getUuid();
        meetingFileService.delByMeetingId(projectId);
        MeetingFile meetingFile = new MeetingFile();
        String id = IdUtil.objectId();
        meetingFile.setMeetingId(projectId);
        meetingFile.setFileType(MeetingFileType.OUTLINE_PROJECT_WORD.getCode());
        meetingFile.setId(id);
        meetingFile.setFileExt(FileNameUtil.getSuffix(outlineProjectPO.getFileName()));
        meetingFile.setFilePath(outlineProjectPO.getEcmId());
        meetingFile.setFileName(outlineProjectPO.getFileName());
        meetingFileService.uploadFile(meetingFile);

        return MessageBean.success("保存监护大纲文件成功");

    }

    /**
     * 报价清单列表
     *
     * @param projectId
     * @param response
     * @param userAgent
     * @return
     */
    @GetMapping("/list/priceList/{projectId}")
    public MessageBean allPriceList(@PathVariable String projectId, HttpServletResponse response, @RequestHeader(value = "User-Agent", required = false, defaultValue = "") String userAgent) {
        List<MeetingFile> meetingFiles = meetingFileService.qryByMeetingIdAndType(projectId, MeetingFileType.PRICE_LIST);
        return MessageBean.success("获取报价单列表成功", meetingFiles);
    }

    /**
     * 生成报价清单
     *
     * @param projectId
     * @param response
     * @param userAgent
     * @return
     */
    @GetMapping("/generate/priceList/{projectId}")
    public MessageBean genPriceList(@PathVariable String projectId, HttpServletResponse response, @RequestHeader(value = "User-Agent", required = false, defaultValue = "") String userAgent) {
        String fileId = outLineProjectService.genPriceList(projectId);
        return MessageBean.success("生成报价单成功", fileId);
    }

    /**
     * 下载报价清单
     *
     * @param fileId
     * @param response
     * @param userAgent
     * @return
     */
    @GetMapping("/download/priceList/{fileId}")
    public void downloadPriceList(@PathVariable String fileId, HttpServletResponse response, @RequestHeader(value = "User-Agent", required = false, defaultValue = "") String userAgent) {
        MeetingFile meetingFile = meetingFileService.qryMeetingFileById(fileId);
        InputStream inputStream = minIoUtil.getObject(MinIoUtil.MEETING_BUCKET, meetingFile.getFilePath());

        String fileName = meetingFile.getFileName();
        try {
            if (
                    userAgent.toUpperCase().contains("MSIE") ||
                            userAgent.contains("Trident/7.0")) {
                fileName = java.net.URLEncoder.encode(fileName, "UTF-8");

            } else {
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            }

            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            response.setCharacterEncoding("UTF-8");

            IoUtil.copy(inputStream, response.getOutputStream());

        } catch (Exception e) {
            throw new BIZException("下载文件失败", e);
        }
    }


    /**
     * 预览报价清单
     *
     * @param type      1 fileId 2 projectId
     * @param id
     * @param response
     * @param userAgent
     */
    @GetMapping("/preview/priceList/{type}/{id}")
    public void previewPriceList(@PathVariable String id, HttpServletResponse response, @RequestHeader(value = "User-Agent", required = false, defaultValue = "") String userAgent, @PathVariable String type) {
        MeetingFile meetingFile = null;
        if (Objects.equals("1", type)) {
            meetingFile = meetingFileService.qryMeetingFileById(id);
        } else {
            meetingFile = meetingFileService.qryByMeetingIdAndType(id, MeetingFileType.PRICE_LIST).get(0);
        }


        InputStream inputStream = minIoUtil.getObject(MinIoUtil.MEETING_BUCKET, meetingFile.getFilePath());

        String fileName = meetingFile.getFileName().replace("xlsx", "pdf");
        try {
            if (
                    userAgent.toUpperCase().contains("MSIE") ||
                            userAgent.contains("Trident/7.0")) {
                fileName = java.net.URLEncoder.encode(fileName, "UTF-8");

            } else {
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            }
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setContentType(FileUtil.getMimeType(fileName));
            response.setCharacterEncoding("UTF-8");
            Workbook workbook = new Workbook();


            workbook.loadFromStream(inputStream);
            ConverterSetting converterSetting = new ConverterSetting();
            converterSetting.setSheetFitToPage(true);
            workbook.setConverterSetting(converterSetting);
            Worksheet worksheet = workbook.getWorksheets().get(0);
            worksheet.saveToPdfStream(response.getOutputStream());

        } catch (Exception e) {
            throw new BIZException("下载文件失败", e);
        }
    }


    /**
     * 报价单文件上传
     *
     * @param projectId
     */

    @PostMapping("/upload/priceList/{projectId}")
    public MessageBean upload(@RequestParam("file") MultipartFile[] files, @PathVariable String projectId) {
        for (MultipartFile file : files) {
            try (InputStream inputStream = file.getInputStream();) {
                String ext = FileNameUtil.getSuffix(file.getOriginalFilename());
                String id = IdUtil.objectId() + "." + ext;
                minIoUtil.putObject(MinIoUtil.MEETING_BUCKET, id, inputStream, file.getContentType());
                MeetingFile meetingFile = new MeetingFile();
                meetingFile.setId(IdUtil.objectId());
                meetingFile.setFileType(MeetingFileType.PRICE_LIST.getCode());
                meetingFile.setMeetingId(projectId);
                meetingFile.setFileName(file.getOriginalFilename());
                meetingFile.setFilePath(id);
                meetingFile.setFileExt(ext);
                meetingFileService.uploadFile(meetingFile);
            } catch (Exception e) {
                return MessageBean.success("文件上传失败");
            }
        }
        return MessageBean.success("文件上传成功");
    }


    /**
     * 获取报价单数量
     *
     * @param projectId
     * @return
     */
    @GetMapping("/count/priceList/{projectId}")
    public MessageBean count(@PathVariable String projectId) {
        long count = meetingFileService.qryByMeetingIdAndType(projectId, MeetingFileType.PRICE_LIST).size();

        return MessageBean.success("获取报价单数量成功", count);

    }

}
